#include "../../src/box/coro_runner.hh"
#include "../../src/detail/service_context_impl.hh"
#include "../../src/http/http_base.hh"
#include "../../src/scheduler/scheduler.hh"
#include "../framework/unittest.hh"
#include <iostream>

FIXTURE_BEGIN(test_service_context)

using namespace kratos;

CASE(TestWriteLogWithoutBox) {
  service::ServiceContextImpl ctx(nullptr);
  ctx.diagnose("a");
  ctx.except("a");
  ctx.fail("a");
  ctx.fatal("a");
  ctx.info("a");
  ctx.warn("a");
  ctx.verbose("a");
  ASSERT_TRUE(nullptr != ctx.new_coro_runner());
  ASSERT_TRUE(nullptr != ctx.new_scheduler());
  ASSERT_TRUE(nullptr != ctx.new_http());
  auto *ptr = ctx.allocate(10);
  ASSERT_TRUE(nullptr != ptr);
  ctx.deallocate(ptr);
  auto &allocator = ctx.get_allocator();
  auto p = allocator.make_shared_array<char>(123);
  struct A {};
  auto p1 = allocator.make_shared_array<A>(10);
  ASSERT_TRUE(p1);
  struct B {};
  auto p2 = allocator.make_shared<B>();
  ASSERT_TRUE(p2);
  auto p3 = allocator.make_shared<int>();
  ASSERT_TRUE(p3);
  struct C {
    virtual ~C() {}
    void func() {}
  };
  auto p4 = allocator.make_shared_array<C>(1);
  ASSERT_TRUE(!p4);

  auto up = allocator.make_unique_array<char>(123);
  auto up1 = allocator.make_unique_array<A>(10);
  ASSERT_TRUE(up1);
  auto up2 = allocator.make_unique<B>();
  ASSERT_TRUE(up2);
  auto up3 = allocator.make_unique<int>();
  ASSERT_TRUE(up3);
  auto up4 = allocator.make_unique_array<C>(1);
  ASSERT_TRUE(!up4);

  auto p_debug = allocator.make_shared_array_debug<char>(123);
  auto p1_debug = allocator.make_shared_array_debug<A>(10);
  ASSERT_TRUE(p1);
  auto p2_debug = allocator.make_shared_debug<B>(__FILE__, __LINE__);
  ASSERT_TRUE(p2);
  auto p3_debug = allocator.make_shared_debug<int>(__FILE__, __LINE__);
  ASSERT_TRUE(p3);
  auto p4_debug = allocator.make_shared_array_debug<C>(1);
  ASSERT_TRUE(!p4);

  allocator.snapshot();

  auto up_debug = allocator.make_unique_array_debug<char>(123);
  auto up1_debug = allocator.make_unique_array_debug<A>(10);
  ASSERT_TRUE(up1);
  struct D {
      D(int, int) {}
  };
  auto up2_debug = allocator.make_unique_debug<D>(__FILE__, __LINE__, 1, 1);
  ASSERT_TRUE(up2);
  auto up3_debug = allocator.make_unique_debug<int>(__FILE__, __LINE__);
  ASSERT_TRUE(up3);
  auto up4_debug = allocator.make_unique_array_debug<C>(1);
  ASSERT_TRUE(!up4);
  allocator.snapshot();
  allocator.dump(std::cout);
}

FIXTURE_END(test_service_context)
